//
//
//
//  @ Project : Untitled
//  @ File Name : PageStrategy.h
//  @ Date : 2011/4/15
//  @ Author : 
//
//


#if !defined(_PAGESTRATEGY_H)
#define _PAGESTRATEGY_H

#include "Page.h"

namespace PageSystem
{
	class StreamSerialiser;
	class PagedWorldSection;
	class PageManager;
	class PagedWorldSection;
	class PageCamera;
	/** \addtogroup Optional Components
	*  @{
	*/
	/** \addtogroup Paging
	*  Some details on paging component
	*/
	/*@{*/


	/** Abstract marker class representing the data held against the PagedWorldSection
	which is specifically used by the PageStrategy.
	*/
	class PageStrategyData //: public PageAlloc
	{
	public:
		PageStrategyData() {}
		virtual ~PageStrategyData() {}

		/// Load this data from a stream (returns true if successful)
		virtual bool load(StreamSerialiser& stream) = 0;
		/// Save this data to a stream
		virtual void save(StreamSerialiser& stream) = 0;


	};


	/** Defines the interface to a strategy class which is responsible for deciding
	when Page instances are requested for addition and removal from the 
	paging system.
	@remarks
	The interface is deliberately light, with no specific mention of requesting
	new Page instances. It is entirely up to the PageStrategy to respond
	to the events raised on it and to call methods on other classes (such as
	requesting new pages). 
	*/
	class PageStrategy //: public PageAlloc
	{
	protected:
		String mName;
		PageManager* mManager;
	public:
		PageStrategy(const String& name, PageManager* manager)
			: mName(name), mManager(manager)
		{

		}

		virtual ~PageStrategy() {}

		const String& getName() const { return mName; }
		PageManager* getManager() const { return mManager; }

		/// Called when the frame starts
		virtual void frameStart(Real timeSinceLastFrame, PagedWorldSection* section) {}
		/// Called when the frame ends
		virtual void frameEnd(Real timeElapsed, PagedWorldSection* section) {}
		/** Called when a PageCamera is used for any kind of rendering.
		@remarks
		This is probably the primary way in which the strategy will request
		new pages. 
		@param cam PageCamera which is being used for rendering. Class should not
		rely on this pointer remaining valid permanently because no notification 
		will be given when the PageCamera is destroyed. 
		*/
		virtual void notifyPageCamera(PageCamera* cam, PagedWorldSection* section) {}

		/** Create a PageStrategyData instance containing the data specific to this
		PageStrategy. 
		@par
		This data will be held by a given PagedWorldSection and the structure of
		the data will be specific to the PageStrategy subclass.
		*/
		virtual PageStrategyData* createData() = 0;

		/** Destroy a PageStrategyData instance containing the data specific to this
		PageStrategy. 
		@par
		This data will be held by a given PagedWorldSection and the structure of
		the data will be specific to the PageStrategy subclass.
		*/
		virtual void destroyData(PageStrategyData* d) = 0;

		/** Update the contents of the passed in SceneNode to reflect the 
		debug display of a given page. 
		@remarks
		The PageStrategy is to have complete control of the contents of this
		SceneNode, it must not be altered / added to by others.
		*/
		//virtual void updateDebugDisplay(Page* p, SceneNode* sn) = 0;

		/** Get the page ID for a given world position. 
		@returns The page ID
		*/
		virtual PageID getPageID(const Common::Vector3& worldPos, PagedWorldSection* section) = 0;
	};

	/*@}*/
	/*@}*/
}
#endif  //_PAGESTRATEGY_H
